package com.fingard.dsp.bank.directbank.swiftpass01;

import java.util.HashMap;

import com.fingard.constant.Format;
import com.fingard.dsp.bank.directConfig.ActSetItem;
import com.fingard.dsp.bank.directbank.PaymentState;
import com.fingard.dsp.bank.reqrespobj.unifiedorder.ReqQueryOrder;
import com.fingard.dsp.bank.reqrespobj.unifiedorder.ReqUnifiedOrder;
import com.fingard.dsp.bank.reqrespobj.unifiedorder.RetAtsQueryOrder;
import com.fingard.dsp.bank.reqrespobj.unifiedorder.RetAtsUnifiedOrder;
import com.fingard.net.ConnState;
import com.fingard.text.StringHelper;
import com.fingard.xml.XmlTextReader;

public class SpUnifiedOrder extends SwiftPass01Base {
	public RetAtsUnifiedOrder submitUnifiedOrder(ReqUnifiedOrder p_req) {
		RetAtsUnifiedOrder retAts = new RetAtsUnifiedOrder();
		retAts.rdSeq = p_req.rdSeq;
		
		try{
			ActSetItem actItem = this.getBankConfig().getActSetItemByAny(p_req.ownAct, p_req.merchantId, p_req.appId, "unifiedorder");
			if(actItem == null){
				retAts.respCode = "0";
				retAts.respInfo = "未找到账号[" + p_req.ownAct + "]商户配置信息";
				retAts.qrInfo = "";
				
				return retAts;
			}
			
			HashMap<String,String> mapParams = new HashMap<String,String>();
			
			String appid = p_req.appId;
			if (StringHelper.isNullOrEmpty(appid)) {
				appid = actItem.appId;
			}
			
			if(reqHeader.transType.equals("SubmitJSAPIOrder")){
				// openId
				String openId = p_req.openid;
				if (StringHelper.isNullOrEmpty(openId)) {
					if(StringHelper.isNullOrEmpty(p_req.code)){
						retAts.respCode = "-1";
						retAts.respInfo = "Code和Openid不能同时为空";
						
						return retAts;
					} else {
						if(StringHelper.isNullOrEmpty(actItem.appSecret)){
							retAts.respCode = "-1";
							retAts.respInfo = "未配置公众号的appsecret";
							
							return retAts;
						} else {
							HashMap<String,String> hashOpenid = getOpenid(appid, actItem.appSecret, p_req.code);
							
							if(hashOpenid.get("RespCode").equals("0")){
								if(hashOpenid.containsKey("openid")){
									openId = hashOpenid.get("openid");
								} else {
									retAts.respCode = "-1";
									
									String errcode = "";
									if(hashOpenid.containsKey("errcode")){
										errcode = hashOpenid.get("errcode");
									}
									
									String errmsg = "";
									if(hashOpenid.containsKey("errmsg")){
										errmsg = hashOpenid.get("errmsg");
									}
									
									retAts.respInfo = StringHelper.joinNotEmpty("-", errcode, errmsg);
									
									return retAts;
								}
							} else {
								retAts.respCode = "-1";
								retAts.respInfo = hashOpenid.get("RespInfo");
								
								return retAts;
							}
						}
					}
				}
				
				mapParams.put("service", "pay.weixin.jspay");
				mapParams.put("version", "1.0");
				mapParams.put("is_raw", "1");
				mapParams.put("sub_openid", openId);
			}
			else{
				/** 微信扫码付和支付宝扫码付通过指令代码区分
				 * SPNATIVE01:微信扫码付
				 * SPNATIVE02:支付宝扫码付
				 */
				if (p_req.reqHeader.commandCode.equals("SPNATIVE01")) {
					mapParams.put("service", "pay.weixin.native");// 接口类型
					mapParams.put("version", "1.0");
				}else {
					mapParams.put("service", "pay.alipay.native");
					mapParams.put("version", "2.0");
				}
			}
			mapParams.put("charset", getCharset());
			mapParams.put("sign_type", "MD5");// 签名方式
			
			String mch_id = p_req.merchantId;
			if(StringHelper.isNullOrEmpty(mch_id)){
				mch_id = actItem.merchantId;
			}
			mapParams.put("mch_id", mch_id);
			
			mapParams.put("out_trade_no", p_req.rdSeq);// 商户订单号
			
			if(StringHelper.hasAnyChar(actItem.termId)){
				mapParams.put("device_info", actItem.termId);// 终端设备号
			}
			
			if(StringHelper.hasAnyChar(p_req.description)){
				mapParams.put("body", p_req.description);
			}
			else if(StringHelper.hasAnyChar(p_req.memo)){
				mapParams.put("body", p_req.memo);
			}
			else{
				mapParams.put("body", p_req.rdSeq);
			}
			
			if(StringHelper.hasAnyChar(p_req.attach)){
				mapParams.put("attach", p_req.attach);
			}
			String total_fee = StringHelper.amountMultiply100(p_req.amount);
			mapParams.put("total_fee", total_fee);// 总金额
			
			mapParams.put("mch_create_ip", actItem.createIP);// 终端IP
			
			String notify_url = actItem.notifyURL;
			if(StringHelper.isNullOrEmpty(notify_url)){
				notify_url = bankFront.getUrl("unifiedorderNotify");
			}
			mapParams.put("notify_url", notify_url);
			
			if(StringHelper.hasAnyChar(p_req.timeStart)){
				mapParams.put("time_start", Format.DateTime14Format.format(p_req.getTimeStart()));// 订单生成时间
			}
			if(StringHelper.hasAnyChar(p_req.timeExpire)){
				mapParams.put("time_expire", Format.DateTime14Format.format(p_req.getTimeExpire()));// 订单失效时间
			}
			
			if(StringHelper.isNullOrEmpty(p_req.productId)){
				mapParams.put("product_id", p_req.productId);// 商品ID
			}
			
			if (StringHelper.hasAnyChar(p_req.certNumber) || StringHelper.hasAnyChar(p_req.oppActName) || StringHelper.hasAnyChar(p_req.cellPhone)) {
				mapParams.put("fix_buyer", "1");
			} else {
				mapParams.put("fix_buyer", "0");
			}
			
			mapParams.put("user_creid", p_req.certNumber);
			mapParams.put("user_truename", p_req.oppActName);
			mapParams.put("user_certtype", "01");
			mapParams.put("user_mobile", p_req.cellPhone);
			
			String nonce_str = get_nonce_str();
			mapParams.put("nonce_str", nonce_str);
			
			String signMsg = signMessage(mapParams, actItem.saltKey);
			mapParams.put("sign", signMsg);

			String tmpXml = buildXml(mapParams);
			
			// 发银行
			String[] tmpStrRet = sendToBank(tmpXml, "unifiedorder");
			
			// 解析银行返回
			if(tmpStrRet[0].length() == 0){
				StringBuilder tmpSbMsg = new StringBuilder();
				XmlTextReader tmpBkReader = loadBankRespXmlReader(tmpStrRet[1], tmpSbMsg);
				
				if(tmpBkReader != null) {
					String status = tmpBkReader.getFirstText("/xml/status");
					String message = tmpBkReader.getFirstText("/xml/message");
					
					if(status!= null && status.equals("0")){
						boolean verifyResult = this.verifySign(tmpStrRet[1], actItem.saltKey, tmpSbMsg);
						if(verifyResult){
							String result_code = tmpBkReader.getFirstText("/xml/result_code");
							
							if(result_code != null && result_code.equals("0")){
								retAts.respCode = "0";
								retAts.transState = "SUCCESS";
								if(p_req.reqHeader.transType.equals("SubmitQROrder")){
									retAts.qrType = "";
									retAts.qrInfo = tmpBkReader.getFirstText("/xml/code_url");
									retAts.qrImgUrl = tmpBkReader.getFirstText("/xml/code_img_url");
								}
								else if(p_req.reqHeader.transType.equals("SubmitJSAPIOrder")){
									retAts.customHashMap = new HashMap<String,String>();
									
									String pay_info = StringHelper.trimEnd(tmpBkReader.getFirstText("/xml/pay_info"),"}");
									String[] jsonValues = pay_info.split(",");
									for(int i=0;i<jsonValues.length;i++){
										String[] keyValue = jsonValues[i].split(":");
										if(keyValue.length == 2){
											if(keyValue[0].indexOf("appId")>=0){
												retAts.customHashMap.put("appId", keyValue[1].trim().replace("\"", ""));
											}
											else if(keyValue[0].indexOf("timeStamp")>=0){
												retAts.customHashMap.put("timeStamp", keyValue[1].trim().replace("\"", ""));
											}
											else if(keyValue[0].indexOf("signType")>=0){
												retAts.customHashMap.put("signType", keyValue[1].trim().replace("\"", ""));
											}
											else if(keyValue[0].indexOf("package")>=0){
												retAts.customHashMap.put("package", keyValue[1].trim().replace("\"", ""));
											}
											else if(keyValue[0].indexOf("nonceStr")>=0){
												retAts.customHashMap.put("nonceStr", keyValue[1].trim().replace("\"", ""));
											}
											else if(keyValue[0].indexOf("paySign")>=0){
												retAts.customHashMap.put("paySign", keyValue[1].trim().replace("\"", ""));
											}
										}
									}
								}
							}else{
								retAts.respCode = "-1";
								retAts.payInfoCode = tmpBkReader.getFirstText("/xml/err_code");
								retAts.respInfo = tmpBkReader.getFirstText("/xml/err_msg");
							}
						}else {
							retAts.respCode = "-1";
							retAts.respInfo = tmpSbMsg.toString();
						}
					}else {
						retAts.respCode = "-1";
						retAts.transState = PaymentState.FAIL_Payment;
						retAts.respInfo = message;
					}
				}else {
					retAts.respCode = "-1";
					retAts.respInfo = tmpSbMsg.toString();
				}
			}else if (tmpStrRet[0].equals(ConnState.FAIL)){
				retAts.respCode = "-1";
				retAts.respInfo = tmpStrRet[1];
				retAts.transState = PaymentState.FAIL_Payment;
				retAts.payInfoCode = tmpStrRet[0];
			}else {
				retAts.respCode = "-1";
				retAts.respInfo = tmpStrRet[1];
			}
		}catch(Exception e) {
			retAts.respCode = "-1";
			retAts.respInfo = e.getMessage();
			WriteBankLogLn(e);
		}
		
		return retAts;
	}

	public RetAtsQueryOrder queryUnifiedOrder(ReqQueryOrder p_req) {
		RetAtsQueryOrder retAts = new RetAtsQueryOrder();
		retAts.rdSeq = p_req.rdSeq;
		
		try{
			ActSetItem actItem = this.getBankConfig().getActSetItemByAny(p_req.ownAct, p_req.merchantId, p_req.appId, "unifiedorder");
			if(actItem == null){
				retAts.respCode = "-1";
				retAts.respInfo = "未找到账号[" + p_req.ownAct + "]商户配置信息";
				return retAts;
			}

			HashMap<String,String> mapParams = new HashMap<String,String>();
			
			mapParams.put("service", "unified.trade.query");
			
			/** 
			 * 微信扫码付和支付宝扫码付通过指令代码区分
			 * 		SPNATIVE01:微信扫码付
			 * 		SPNATIVE02:支付宝扫码付
			 */
			if (p_req.reqHeader.commandCode.equals("SPNATIVE01")) {
				mapParams.put("version", "1.0");
			}else {
				mapParams.put("version", "2.0");
			}
			
			mapParams.put("charset", getCharset());
			mapParams.put("sign_type", "MD5");
			
			String mch_id = p_req.merchantId;
			if(StringHelper.isNullOrEmpty(mch_id)){
				mch_id = actItem.merchantId;
			}
			mapParams.put("mch_id", mch_id);
			
			mapParams.put("out_trade_no", p_req.rdSeq);
			
			String nonce_str = get_nonce_str();
			mapParams.put("nonce_str", nonce_str);
			
			String signMsg = signMessage(mapParams, actItem.saltKey);
			mapParams.put("sign", signMsg);

			String tmpXml = buildXml(mapParams);
			
			String[] tmpStrRet = sendToBank(tmpXml, "unifiedorder");
			
			if(tmpStrRet[0].length() == 0){
				StringBuilder tmpSbMsg = new StringBuilder();
				XmlTextReader tmpBkReader = loadBankRespXmlReader(tmpStrRet[1], tmpSbMsg);
				
				if(tmpBkReader != null){
					String status = tmpBkReader.getFirstText("/xml/status");
					String message = tmpBkReader.getFirstText("/xml/message");
					
					if(status!= null && status.equals("0")){
						boolean verifyResult = this.verifySign(tmpStrRet[1], actItem.saltKey, tmpSbMsg);
						
						if(verifyResult){
							String result_code = tmpBkReader.getFirstText("/xml/result_code");
							String err_code = tmpBkReader.getFirstText("/xml/err_code");
							String err_msg = tmpBkReader.getFirstText("/xml/err_msg");
							String trade_state = tmpBkReader.getFirstText("/xml/trade_state");
							
							retAts.respCode = "0";
							retAts.transState = StringHelper.joinNotEmpty("+", result_code, err_code, trade_state);
							
							String out_trade_no = tmpBkReader.getFirstText("/xml/out_trade_no");
							if(StringHelper.hasAnyChar(out_trade_no)){
								if(!out_trade_no.equals(p_req.rdSeq)){
									retAts.respCode = "-1";
									retAts.respInfo = "请求流水号"+p_req.rdSeq+"与响应流水号"+out_trade_no+"不一致";
									return retAts;
								}
							}
							retAts.rdSeq = p_req.rdSeq;
							
							retAts.oppBank = tmpBkReader.getFirstText("/xml/bank_type");
							retAts.outTransID = tmpBkReader.getFirstText("/xml/transaction_id");
							retAts.openId = tmpBkReader.getFirstText("/xml/openid");
							retAts.oppAct = tmpBkReader.getFirstText("/xml/buyer_logon_id");

							if(StringHelper.hasAnyChar(err_code)){
								retAts.payInfoCode = err_code;
							}else{
								retAts.payInfoCode = trade_state;
							}
							
							retAts.respInfo = err_msg;

							if(retAts.payInfoCode == null){
								retAts.payInfoCode = "";
							}
							if(retAts.respInfo == null){
								retAts.respInfo = "";
							}
						}else {
							retAts.respCode = "-1";
							retAts.respInfo = tmpSbMsg.toString();
						}
					}else{
						retAts.respCode = "-1";
						retAts.respInfo = message;
					}
				}else{
					retAts.respCode = "-1";
					retAts.respInfo = tmpSbMsg.toString();
				}
			}else{
				retAts.respCode = "-1";
				retAts.respInfo = tmpStrRet[1];
			}
		}catch(Exception ex){
			ex.printStackTrace();
			retAts.respCode = "-1";
			retAts.respInfo = ex.getMessage();
			WriteBankLogLn(ex);
		}
		
		return retAts;
	}
}
